#import "Query.h"

@implementation Query

+(int)getVersion{
	Packet *p=[Packet new];
	[p initWithAction:@"getversion" andContent:nil];
	id ret=[Query query:p];
	if(ret==nil){
		errorMsg=ERROR_QUERY_RETURN_NIL;
		return -1;
	}
	id ver=[ret valueForKey:@"content"];
	[p release];
	[ret release];
	if(ver==nil || [ver isKindOfClass:[NSNull class]])return -1;
	else return [ver intValue];
}

+(NSArray *)listMenu{
	NSArray * menus=[Query getList:@"listmenu"];
	NSArray * ret=[NSArray new];
	for(int i=0;i<[menus count];i++){
		ret=[ret arrayByAddingObject:[Menu fromJsonObj:[menus objectAtIndex:i]]];
	}
	[menus release];
	return ret;
}

+(NSArray *)listCategory{
	NSArray * cates=[Query getList:@"listcategory"];
	NSArray * ret=[NSArray new];
	for(int i=0;i<[cates count];i++){
		ret=[ret arrayByAddingObject:[Category fromJsonObj:[cates objectAtIndex:i]]];
	}
	[cates release];
	return ret;
}

+(int)startTable:(int)tableNum{
	Packet *p=[Packet new];
	[p initWithAction:@"starttable" andContent:[NSNumber numberWithInt:tableNum]];
	id ret=[Query query:p];
	if(ret==nil){
		errorMsg=ERROR_QUERY_RETURN_NIL;
		return -1;
	}
	id status=[ret valueForKey:@"content"];
	if(status==nil || [status isKindOfClass:[NSNull class]])return -2;
	else return [status intValue];
}

+(int)submitOrder:(Order*)order{
	Packet *p=[Packet new];
	[p initWithAction:@"submitorder" andContent:[writer stringWithObject:order]];
	id ret=[Query query:p];
	if(ret==nil){
		errorMsg=ERROR_QUERY_RETURN_NIL;
		return -1;
	}
	id status=[ret valueForKey:@"content"];
	if(status==nil || [status isKindOfClass:[NSNull class]])return -2;
	else return [status intValue];
}

+(Order *)getOrder:(int)desknum{
	Packet *p=[Packet new];
	[p initWithAction:@"getorder" andContent:[NSNumber numberWithInt:desknum]];
	id ret=[Query query:p];
	if(ret==nil){
		errorMsg=ERROR_QUERY_RETURN_NIL;
		return -1;
	}
	ret=[parser objectWithString:[ret valueForKey:@"content"]];
	if(ret==nil)return nil;
	return [Order fromJsonObj:ret];
}

+(int)updateOrder:(Order*)order{
	Packet *p=[Packet new];
	[p initWithAction:@"updateorder" andContent:[writer stringWithObject:order]];
	id ret=[Query query:p];
	if(ret==nil){
		errorMsg=ERROR_QUERY_RETURN_NIL;
		return -1;
	}
	id status=[ret valueForKey:@"content"];
	if(status==nil || [status isKindOfClass:[NSNull class]])return -2;
	else return [status intValue];
}

+(NSArray *)getList:(NSString *)queryName{
	NSArray * lists=[NSArray array];
	Packet *p=[Packet new];
	[p initWithAction:queryName andContent:nil];
	id ret=[Query query:p];
	if(ret==nil){
		errorMsg=ERROR_QUERY_RETURN_NIL;
		return nil;
	}
	if([(NSString*)[ret valueForKey:@"action"] isEqualToString:@"starttransfer"]){
		int n=[[ret valueForKey:@"content"] intValue];
		if(n>0&&n<TOO_BIG){
			NSLog(@"getList start transfer, total %d",n);
			for(int i=0;i<=n;i++){
				ret=[Query recvObj];
				if([[ret valueForKey:@"action"] isEqualToString:@"endtransfer"]){
					break;
				}else{
					NSString *s=(NSString *)[ret valueForKey:@"content"];
					lists=[lists arrayByAddingObject:[parser objectWithString:s]];
				}
			}
		}else{
			NSLog(@"error: Query.listmenu, n is negative or too large: %d",n);
		}
	}else{
		NSLog(@"error: Query.getList, the first packet recved is not starttransfer");
	}
	[p release];
	[ret release];
	return lists;
}

+(void)init:(NSString *)ip port:(int)port{
	con=[Connector alloc];
	[con init:ip port:port];
	parser = [SBJsonParser new];
	writer=[SBJsonWriter new];
	errorMsg=nil;
}

+(id)sendQuery:(id)o{		// send a packet
	if(con==nil){
		NSLog(@"error- Query.query: con == nil");
		return nil;
	}
	if(o==nil){
		NSLog(@"error- Query.query: o == nil");
		return nil;
	}
	if(writer==nil){
		NSLog(@"error: Query.query: please init the query before using it.");
		return nil;
	}
	NSString *json = [writer stringWithObject:o];
	NSLog(@"query: send json = %@ \n",json);
//	NSLog(@"error trace: %@",[writer error]);
	[con sendStr:json];
}

+(id)recvObj{			// recv a packet, and returns a obj parsed
	if(con==nil){
		NSLog(@"error- Query.query: con == nil");
		return nil;
	}
	return [parser objectWithString:[con recvPacket]];
}

+(id)query:(id)o{			// send query and recv the first packet
	[Query sendQuery:o];
	NSString * ret=[con recvPacket];
	NSLog(@"recv json: %@",ret);
	return [parser objectWithString:ret];
	//NSObject* parsed_obj = [[[[SBJsonParser alloc] init] autorelease] objectWithData: data];
}

+(void)finish{
	[writer release];
	[parser release];
	if(errorMsg!=nil)[errorMsg release];
	[con finish];
	[con dealloc];
	con=nil;
	writer=nil;
	parser=nil;
}

@end
